#pragma once
#include <iostream>
#include <string>

using namespace std;

const string blank_space_sep = " ";
const string protocol_set = "\n";

//封装报头 "len"\n"x + y"\n
string Encode(string &content)
{ 
    // 封装报头
    string packet = to_string(content.size());
    packet += protocol_set;
    packet += content;
    packet += protocol_set;

    return packet;
}


// "len"\n "x op y" \n
bool Decode(string& package, string* content)
{
    size_t pos = package.find(protocol_set);
    if(pos == string::npos)
        return false;
    //数据的长度:
    string len_str = package.substr(0, pos);
    size_t len = stoi(len_str);

    //序列化之后的长度
    size_t total_len = len_str.size() + len + 2;
    if(package.size() < total_len) 
        return false;
    
    *content = package.substr(pos+1, len);

    return true;
}

//发送请求方
class Request
{
public:
    Request(int data1, int data2, char op)
        : x(data1), y(data2), oper(op)
    {}

    Request()
    {}

    //"1 + 2"
    bool Serialize(string *out)
    {
        string s = to_string(x);
        s += blank_space_sep;
        s += oper;
        s += blank_space_sep;
        s += to_string(y);

        *out = s;
        return true;
    }

    //"1 + 2" 
    //反序列化
    bool Desserialize(const string& in)
    {
        //oper之前的为left部分;
        size_t left = in.find(blank_space_sep);
        if(left == string::npos) 
            return false;
        string part_x = in.substr(0, left);

        //oper之后的为right部分
        size_t right = in.rfind(blank_space_sep);
        if(right == string::npos)
            return false;
        string part_y = in.substr(right+1);

        //
        if(left + 2 != right)
            return false;
        x = stoi(part_x);
        y = stoi(part_y);
        return true;
    }

    void DebugPrint()
    {
        cout << "新请求构建完成: " << x << oper << y << "=?" << endl;
    }

public:
    int x;
    int y;
    char oper;
};


//数据接受方
class Response
{
public:
    Response(int res, int co)
        : result(res), code(co)
    {}
    
    Response()
    {}

    //序列化 "result code"
    bool Serialize(string *out)
    {
        string s = to_string(result);
        s += blank_space_sep;
        s += to_string(code);

        *out = s;
        return true;
    }

    //反序列化 "result code"
    bool Desserialize(string& in)
    {
        size_t pos = in.find(blank_space_sep);
        if(pos == string::npos) 
            return false;
        string part_left = in.substr(0, pos);
        string part_right = in.substr(pos+1);

        
        result = stoi(part_left);
        code = stoi(part_right);
        return true;
    }

    void DebugPrint()
    {
        cout << "结果响应完成, result: " << result << ", code:" << code << endl;
    }
public:
    int result;
    int code;
};